package com.xzq.socket.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author xzq
 * @Description //TODO
 * @Date 2021/11/18 11:27
 * @Version 1.0.0
 **/
public class AIOServer {
    private final int port;

    public AIOServer(int port) {
        this.port = port;
        listen();
    }

    private void listen() {
        try {
            ExecutorService pool = Executors.newCachedThreadPool();
            AsynchronousChannelGroup threadGroup = AsynchronousChannelGroup.withCachedThreadPool(pool, 1);
            final AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
            server.bind(new InetSocketAddress(port));
            System.out.println("服务启动：监听端口：" + pool);

            server.accept(null, new AcceptHandler(server));
            Thread.sleep(Integer.MAX_VALUE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel,Object>{
        private final AsynchronousServerSocketChannel ssc;

        public AcceptHandler(AsynchronousServerSocketChannel ssc) {
            this.ssc = ssc;
        }

        @Override
        public void completed(AsynchronousSocketChannel sc, Object attachment) {
            ByteBuffer buffer = ByteBuffer.allocate(128);
            //读事件由ReadHandler处理
            sc.read(buffer, buffer,new ReadHandler(sc));
            ssc.accept(null, this);
        }

        @Override
        public void failed(Throwable exc, Object attachment) {

        }
    }

    public static class ReadHandler implements CompletionHandler<Integer,ByteBuffer>{
        private final AsynchronousSocketChannel sc;

        public ReadHandler(AsynchronousSocketChannel sc) {
            this.sc = sc;
        }

        @Override
        public void completed(Integer len, ByteBuffer attachment) {
            if (len == -1) {
                try {
                    sc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            attachment.flip();
            System.out.println(Charset.forName("gbk").decode(attachment));
            attachment.clear();
            //再次调用read处理下一个read事件
            sc.read(attachment, attachment, this);
        }
        @Override
        public void failed(Throwable exc, ByteBuffer attachment) {

        }
    }
    public static void main(String[] args) {
        int port = 9999;
        new AIOServer(port);
    }
}
